package neu.soft.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import neu.soft.constant.FinancialEnumGetter;
import neu.soft.entity.*;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author 李博
 * 提供map转特定的对象方法，提供从map获取object对象变为特定类的集合
 * 提供枚举类，日期类转换或者格式化的方法。
 * 提供特定类的类转换
 */
public class TypeConvert {

    //Object转Map
    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        Class<?> cla = obj.getClass();
        Field[] fields = cla.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String keyName = field.getName();
            Object value = field.get(obj);
            if (value == null)
                value = "";
            map.put(keyName, value);
        }
        return map;
    }

    //Map转Object
    public static Object getMapToObject(Map<Object, Object> map, Class<?> objClass) throws Exception {
        if (map == null)
            return null;
        Object obj = objClass.newInstance();
        Class<?> aClass = obj.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            field.setAccessible(true);
            if (map.containsKey(field.getName())) {
                field.set(obj, map.get(field.getName()));
            }
        }
        return obj;
    }

    //jsonList互换
    public static <T> List<T> jsonArrayToList(String json, Class<T> elementClass) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        CollectionType listType =
                objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass);
        return objectMapper.readValue(json, listType);
    }


    public static GoodInfo goodInfoConverter(NormalOrderInfo normalOrderInfo) {
        return new GoodInfo(normalOrderInfo.getShoppingCode(), normalOrderInfo.getShoppingName(), normalOrderInfo.getShoppingNum(), normalOrderInfo.getShoppingPrice(), 0);
    }


    public static FinancialPurchaseOrder purchaseOrderConverter(OperationPurchaseOrder operationPurchaseOrder) {
        FinancialPurchaseOrder financialPurchaseOrder = new FinancialPurchaseOrder();
        financialPurchaseOrder.setPurchaseOrderId(operationPurchaseOrder.getPurchaseOrderId());
        financialPurchaseOrder.setOrderId(operationPurchaseOrder.getOrderId());
        financialPurchaseOrder.setPurchasePrice(operationPurchaseOrder.getPurchasePrice());
        financialPurchaseOrder.setPurchaseType(operationPurchaseOrder.getPurchaseType());
        financialPurchaseOrder.setVendor(operationPurchaseOrder.getVendor());
        financialPurchaseOrder.setVendorContactPerson(operationPurchaseOrder.getVendorContactPerson());
        financialPurchaseOrder.setVendorContact(operationPurchaseOrder.getVendorContact());
        financialPurchaseOrder.setGoodInfoList(operationPurchaseOrder.getGoodInfoList());
        return financialPurchaseOrder;
    }

    public static InvoiceGoodInfo goodInfoToInvoiceGoodInfo(GoodInfo goodInfo, String measure) {
        InvoiceGoodInfo invoiceGoodInfo = new InvoiceGoodInfo();
        invoiceGoodInfo.setSpecificationsModels("default");
        invoiceGoodInfo.setMeasure(measure);
        invoiceGoodInfo.setRate("0");
        invoiceGoodInfo.setTax( new BigDecimal("0.00"));
        invoiceGoodInfo.setInvoiceId(0L);
        invoiceGoodInfo.setGoodCount(goodInfo.getGoodCount());
        invoiceGoodInfo.setGoodId(goodInfo.getGoodId());
        invoiceGoodInfo.setGoodName(goodInfo.getGoodName());
        invoiceGoodInfo.setPrice(goodInfo.getPrice());
        invoiceGoodInfo.setGoodOrderId(goodInfo.getGoodOrderId());
        return invoiceGoodInfo;
    }

    public static <T extends Enum<T> & FinancialEnumGetter> String enumToString(Class<T> enumClass, String enumCode) {

        T[] enumConstants = enumClass.getEnumConstants();

        return enumConstants[Integer.parseInt(enumCode)].getEnumValue();
    }

    //获取枚举类元素列表
    public static <T extends Enum<T> & FinancialEnumGetter> List<String> getTypeList(Class<T> enumClass) {

        T[] enumConstants = enumClass.getEnumConstants();//返回此枚举类的元素,此处为泛型，但是泛型约束为实现接口的枚举类型
        List<String> res = new ArrayList<>();
        for (int i = 0;i<enumConstants.length;i++){
            res.add(enumConstants[i].getEnumValue());
        }
        return res;
    }


}
